﻿using Amazon.S3;
using Amazon.S3.Transfer;
using Microsoft.AspNetCore.Mvc;
using Nasty.Core.Config;
using Nasty.Core.LoadParams;
using Nasty.Core.Model;
using Nasty.Core.Registry;
using OfficeOpenXml;

namespace Nasty.Core.Service
{
    public interface IFileService : IAutofacRegister
    {
        public Task<ResultData<string>> SaveFile(IFormFile file, bool isAutoKey = true, string? bucketName = null);

        public Task<(Stream Response, string ContentType)> GetFile(string key, string? bucketName);

        public bool IsExist(string key, string? bucketName);

        public ResultData<string> ExcelExport<T>(List<T> list, List<ExcelItemModel> models, string fileName) where T : class, new();

        public IFormFile ExcelToIFormFile(ExcelPackage package, string fileName = "export.xlsx");
    }

    public class FileService : IFileService
    {
        public required IAmazonS3 S3Client { get; set; }

        public async Task<(Stream Response, string ContentType)> GetFile(string key, string? bucketName)
        {
            bucketName ??= "Normal";

            // 从 S3 获取文件
            var response = await S3Client.GetObjectAsync(SuperConfig.GetBucketName(bucketName), key);

            // 返回文件类型
            var contentType = response.Headers["Content-Type"];

            // 返回文件流作
            return (response.ResponseStream, contentType);
        }

        public async Task<ResultData<string>> SaveFile(IFormFile file, bool isAutoKey = true, string? bucketName = null)
        {
            bucketName ??= "Normal";

            var result = new ResultData<string>();
            if (file == null || file.Length == 0)
            {
                result.IsSuccess = false;
                result.Message = "文件不能为空";
                return result;
            }

            try
            {

                // 生成文件的唯一 Key（可以使用 Guid 或其他逻辑）
                var fileKey = isAutoKey ? $"{Guid.NewGuid().ToString("N")}_{file.FileName}" : file.FileName;

                // 使用 TransferUtility 上传文件
                using (var transferUtility = new TransferUtility(S3Client))
                {
                    using (var fileStream = file.OpenReadStream())
                    {
                        var uploadRequest = new TransferUtilityUploadRequest
                        {
                            InputStream = fileStream,
                            Key = fileKey,
                            BucketName = SuperConfig.GetBucketName(bucketName),
                            ContentType = file.ContentType
                        };

                        await transferUtility.UploadAsync(uploadRequest);
                    }
                }

                result.IsSuccess = true;
                result.Data = fileKey;
                return result;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.Message = ex.Message;
                return result;
            }
        }

        public ResultData<string> ExcelExport<T>(List<T> list, List<ExcelItemModel> models, string fileName) where T : class, new()
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            using (var package = new ExcelPackage())
            {
                var worksheet = package.Workbook.Worksheets.Add("Sheet1");

                // 写入表头
                for (int i = 0; i < models.Count; i++)
                {
                    worksheet.Cells[1, i + 1].Value = models[i].Name;
                }

                // 写入数据
                for (int row = 0; row < list.Count; row++)
                {
                    var item = list[row];
                    for (int col = 0; col < models.Count; col++)
                    {
                        var model = models[col];
                        var prop = typeof(T).GetProperty(model.Field);
                        object value = prop?.GetValue(item);

                        // 格式化
                        if (model.Format != null)
                        {
                            worksheet.Cells[row + 2, col + 1].Value = model.Format(value);
                        }
                        else
                        {
                            worksheet.Cells[row + 2, col + 1].Value = value?.ToString();
                        }
                    }
                }

                // 自动列宽
                worksheet.Cells[worksheet.Dimension.Address].AutoFitColumns();

                var fileService = ServiceLocator.Get<IFileService>();

                var file = ExcelToIFormFile(package, fileName);
                var result = fileService?.SaveFile(file, true, "Temp").Result;
                return result ?? new ResultData<string>() { IsSuccess = false };
            }
        }

        public IFormFile ExcelToIFormFile(ExcelPackage package, string fileName = "export.xlsx")
        {
            var stream = new MemoryStream();
            package.SaveAs(stream);
            stream.Position = 0; // 重置流位置

            // 构建 IFormFile
            var formFile = new FormFile(stream, 0, stream.Length, "file", fileName)
            {
                Headers = new HeaderDictionary(),
                ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
            };
            return formFile;
        }

        public bool IsExist(string key, string? bucketName)
        {
            bucketName ??= "Normal";
            try
            {
                var task = S3Client.GetObjectMetadataAsync(SuperConfig.GetBucketName(bucketName), key);
                task.Wait();
                return true;
            }
            catch (AggregateException ex)
            {
                if (ex.InnerException is Amazon.S3.AmazonS3Exception s3Ex && s3Ex.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    return false;
                }
                throw;
            }
        }
    }
}
